﻿using System.Linq;
using System.Collections.Generic;
using CSRedis;
using Hiver.Util;
using Hiver.Util.Redis;
using Hiver.Cache.Interfaces;

namespace Hiver.Cache
{
    /// <summary>
    /// Redis缓存(不建议使用，建议使用CSRedis默认的RedisHelper方法）
    /// </summary>
    public class RedisCache : ICache
    {
        /// <summary>
        /// 缓存数据库实例
        /// </summary>
        public CSRedisClient db = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="i"></param>
        public RedisCache(int i = 0)
        {
            db = RedisConn.GetDatabase(0);
        }

        /// <summary>
        /// 获得所有复核条件的主键
        /// </summary>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public List<string> GetKeys(string pattern)
        {
            return db.Keys(pattern).ToList();
        }

        #region 字符串缓存

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public object Set(string name, object value)
        {
            db.Set(name, value, 60 * 60 * 1000);
            return value;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public object Set(string name, object value, int timeout = 0)
        {
            db.Set(name, value, timeout);
            return value;
        }

        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object Get(string name)
        {
            return db.Get(name);
        }

        /// <summary>
        /// 判断是否有缓存项
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Has(string name)
        {
            return db.Get(name) != null;
        }

        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object Remove(string name)
        {
            return Set(name, null);
        }

        /// <summary>
        /// 删除缓存键
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public long Delete(string name)
        {
            return db.Del(name);
        }

        /// <summary>
        /// 清空缓存
        /// </summary>
        /// <returns></returns>
        public long Clear()
        {
            Error.Show(5);
            return -1;
        }

        /// <summary>
        /// 刷新缓存
        /// </summary>
        public void Flush()
        {
            Error.Show(6);
        }

        #endregion

        #region List集合缓存

        /// <summary>
        /// 设置List缓存
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public long LSet<T>(string name, params T[] value)
        {
            return db.LPush(name, value);
        }

        /// <summary>
        /// 获得List缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<T> LGet<T>(string name)
        {
            return LGet<T>(name, 0, db.LLen(name));
        }

        /// <summary>
        /// 获得List缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public List<T> LGet<T>(string name, long start, long stop)
        {
            return db.LRange<T>(name, start, stop).ToList();
        }

        /// <summary>
        /// 获得多个键的缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keys"></param>
        /// <returns></returns>
        public List<T> LGet<T>(string[] keys)
        {
            return db.MGet<T>(keys).ToList();
        }

        /// <summary>
        /// 移除所有数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public long LRemove<T>(string name)
        {
            return LRemove<T>(name, 0, db.LLen(name));
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="name"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public long LRemove<T>(string name, long start, long stop)
        {
            long count = 0;
            for (long i = start; i < stop; i++)
            {
                db.LRem(name, i, db.LRem(name, i, db.LIndex<T>(name, i)));
                count++;
            }
            return count;
        }

        /// <summary>
        /// 弹出数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public T LPop<T>(string name)
        {
            return db.LPop<T>(name);
        }

        #endregion

        #region ZSet有序SET缓存

        /// <summary>
        /// 设置ZSet数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="unixTime"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public long ZSet<T>(string name, decimal unixTime, T value)
        {
            return db.ZAdd(name, (unixTime, value));
        }

        /// <summary>
        /// 获得ZSet时间范围数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="minTime"></param>
        /// <param name="maxTime"></param>
        /// <returns></returns>
        public List<T> ZGetMember<T>(string name, decimal minTime, decimal maxTime)
        {
            return db.ZRangeByScore<T>(name, minTime, maxTime).ToList();
        }

        /// <summary>
        /// 获得ZSet时间范围数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="minTime"></param>
        /// <param name="maxTime"></param>
        /// <returns></returns>
        public List<(T, decimal)> ZGet<T>(string name, decimal minTime, decimal maxTime)
        {
            return db.ZRevRangeByScoreWithScores<T>(name, maxTime, minTime).ToList();
        }

        /// <summary>
        /// 获得最新一条记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public T ZGetLast<T>(string name)
        {
            return db.ZScan<T>(name, db.ZCard(name) - 1).Items.FirstOrDefault().member;
        }

        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="name"></param>
        /// <param name="minTime"></param>
        /// <param name="maxTime"></param>
        public long ZRemove(string name, decimal minTime, decimal maxTime)
        {
            return db.ZRemRangeByScore(name, minTime, maxTime);
        }

        #endregion
    }
}